import _ from 'lodash';
import { parse } from '@src/util/querystring';
import Tab from './model/Tab';
import { getRootWindow } from '@src/util/dom';
import FrameHistoryManager from './FrameHistoryManager';
import { platform } from '@src/platform';
import { storageGet, storageSet, storageSetDepth } from '@src/util/storage';
import { sessionStorageSet } from '@src/util/storageV2';

import * as UserCenterApi from '@src/api/UserCenterApi.js';
import * as IMApi from '@src/api/ImApi.js';
import { fetchInitialData } from '@src/api/WorkbenchApi'
// dd crm jsapi
import 'dingtalk-jsapi/entry/union';
import { safeNewDate } from '@src/util/time';
import { getDataFromCRM } from 'dingtalk-design-libs';
import * as fasterPageEnum from 'pub-bbx-global/pageType/dist';
import { openAccurateTab } from '@src/util/platform'
/* hooks */
import { 
  useSelectUserBindTabClose,
  useHiddenAllTab,
  useHiddenOtherTab,
  useSelectUserBindTabInfo,
  useSetStoreBindTabInfo,
} from '@src/component/common/BaseSelectUser/hooks/useFrameTab';
import { isFalsy } from 'pub-bbx-utils';
import { getPcHomePageMenuList } from '@src/api/UserCenterApi'

// import normalizeWheel from '@src/util/normalizeWheel'

const CACHED_FRAMES = ['M_TASK_ALL', 'M_TASK_AUDIT', 'M_TASK_REVIEW'];

const isDev = process.env.NODE_ENV !== 'production';
const postTargetOrigin = isDev ? '*' : `${window.location.origin}`;

const urlMap = {
  taskList: '/task',
  taskAllot: '/task/allot',
  settlement: '/balance/alreadySettlement',
  taskReview: '/task/review',
  taskClose: '/task/close',
  taskPlanList: '/task/planTask/list',
  taskPool: '/task/taskPool',
  event: '/event',
  eventOrder: '/event/order',
};

const storagePageMap = {
  taskList: 'shb_task_list_page_data',
  taskAllot: 'shb_task_allot_page_data',
  settlement: 'shb_settlement_page_data',
  taskReview: 'shb_task_review_page_data',
  taskClose: 'shb_task_close_page_data',
  taskPlanList: 'shb_task_planlist_page_data',
  taskPool: 'shb_task_taskpool_page_data',
  event: 'shb_event_list_page_data',
  eventOrder: 'shb_event_order_page_data',
};

const FrameManager = {
  data() {
    return {
      frameTabs: [],
      // hiddenTabs: [],
      offset: 0,
      nextBtnEnable: false,
      prevBtnEnable: false,
      offsetTransition: false,
      dynamicInfoVisible: false, // 动态信息 显示控制
      lastShowTab: null
    };
  },
  watch: {
    // 监听当前页显示的tab
    frameTabs: {
      handler(tabs, oldTabs) {
        const currentTab = tabs.find(v => v.show);
        currentTab.showTime = safeNewDate().getTime();

        if(this.lastShowTab && currentTab.id !== this.lastShowTab.id) {
          this.trackTabShow();
        }
        // 判断关闭全部关闭其他标签 去除不需要的绑定
        if(tabs.length < oldTabs.length){
          const newBindTabInfo = {};
          const bindTabInfo = useSelectUserBindTabInfo();
          
          tabs.forEach(x => {
            if(bindTabInfo[x.id]) newBindTabInfo[x.id] = bindTabInfo[x.id];
          });

          // 销毁被关闭的标签绑定的tab
          for(let k in bindTabInfo){
            bindTabInfo[k].close();
          }
          useSetStoreBindTabInfo(newBindTabInfo);
        }
        
        this.$eventBus.$emit('watchTab', currentTab);
        this.lastShowTab = currentTab;
        let menus = [ { command: 'all', value: '关闭全部标签' }, { command: 'other', value: '关闭其它标签' } ]
        if(currentTab.id !== 'M_HOME') {
          menus.unshift({ command: 'itself', value: '关闭当前标签' })
        }
        this.frameContextMenus = menus;
        window.frameTabs = tabs;
      },
      deep: true,
    },
    frameContextMenuVisible: {
      immediate: true,
      handler(newValue, oldValue) {
        if(newValue) {
          if(this.$refs.contextMenuRef) {
            this.$refs.contextMenuRef.close()
          }
        }
      }
    }
  },
  methods: {
    /**
     * 切换动态信息显示
     */
    toggleDynamicInfo(isShow = true){
      this.dynamicInfoVisible = isShow;
    },

    // 从paas新建客户
    sendPaasMess(curentData) {
      let fromId = curentData.fromId.replace('frame_tab_', '')
      this.framePostMessage(this.findTab(fromId), {
        action: 'shb.create.customer',
        data: curentData.data,
      });
    },

    // 从paas新建产品
    sendPaasProductMess(curentData) {
      let fromId = curentData.fromId.replace('frame_tab_', '')
      this.framePostMessage(this.findTab(fromId), {
        action: 'shb.create.customer.product',
        data: curentData.data,
      });
    },

    receiveMessage(event) {
      // 不接收其他域名发送的信息
      if (
        process.env.NODE_ENV === 'production'
        && event.origin !== window.location.origin
      )
        return;
      // 验证数据格式
      let eventData = event.data;
      if (!eventData || !eventData.action) return;

      let action = eventData.action;

      if (action == 'shb.system.openFrameTab'){
        console.warn('shb.system.openFrameTab 已废弃,请使用 shb.system.openAccurateTab');
        this.openForFrame(eventData.data);
      }
      if(action == 'shb.system.openAccurateTab'){
        // 提供给规范路由跳转的方法,后期舍弃 shb.system.openFrameTab
        const param = openAccurateTab(eventData.data, true);
        this.openForFrame(param);
      }
      if(action == 'shb.system.backToFromTab'){
        this.backToFromTab(eventData.data);
      }
      if (action == 'shb.system.realodFrameById')
        this.reloadFrameTabById(eventData.data);
      if (action == 'shb.system.closeFrameById')
        this.closeFrameTabById(eventData.data);
      if (action == 'shb.system.setTabTitle')
        this.setFrameTabTitle(eventData.data);
      if (action == 'shb.system.openFrameById')
        this.openFrameById(eventData.data);
      if (action == 'shb.system.mounted') this.mountedFrame(eventData.data);
      if (action == 'shb.system.openRemarkDesign')
        this.openRemarkDesign(eventData.data); // 当组件库迁移出后要移除服务备注相关
      if (action == 'shb.system.openDocumentQuote')
        this.openDocumentQuote(event, eventData.data); // 当组件库迁移出后要移除服务备注相关
      if (action == 'shb.system.openLink') this.openLink(eventData.data); // 当组件库迁移出后要移除服务备注相关
      if (action == 'shb.usefast') this.moduleUseFast(event); // module使用this.$fast
      
      if (action === 'shb.system.setFrameTab') this.setFrameTab(eventData.data);
      if (action === 'shb.system.updateMenus') this.updateMenus(); // 更新菜单
      if (action === 'shb.system.updateMenusV2') this.updateMenusV2(); // 更新菜单
      if (action === 'shb.alert') this.moduleAlert(event);
      if (action === 'shb.down') this.moduleDown();
      if (action === 'shb.system.track') this.track(eventData.data);
      if (action === 'shb.system.showQrCodeDialog') this.showQrCodeDialog();
      if (action === 'shb.system.openServiceManageDesign') this.openServiceManageDesign(eventData.data); // 服务商管理表达设计器
      if (action === 'shb.system.toggleDynamicInfo') this.toggleDynamicInfo(eventData?.data?.isShow); // 切换动态信息显示
      // paas 新建客户
      if (action === 'shb.create.customer') this.sendPaasMess(eventData)
      // paas新建产品
      if (action === 'shb.create.customer.product') this.sendPaasProductMess(eventData)
      if (action === 'shb.system.openChat') this.showChatModal();
      // 打开通知中心 信息公告
      if (action === 'shb.system.openNotice') this.showNoticeModal();
      // 跳转公告详情
      if (action === 'shb.system.noticeDetail') this.openNoticeDetail(eventData);
    },
    openNoticeDetail(eventData){
      const data = eventData?.data || {};
      const openTapParams = {
        id: data.id,
        close: true,
        url: data?.url
      }
      console.log(openTapParams,'openTapParams')
      this.$platform.openTab(openTapParams);
    },
    showNoticeModal() {
      this.$refs.notification?.outShowItem('notice')
    },
    showQrCodeDialog(){
      this.openSaleManager();
    },

    track(tracking){
      window.TDAPP && window.TDAPP.onEvent(tracking);
    },
    moduleAlert(event) {
      // eslint-disable-next-line no-console
      console.log(event, 111);
      platform.alert(event);
    },
    moduleDown() {
      // eslint-disable-next-line no-console
      window.showExportList();
      window.exportPopoverToggle(true);
    },

    setFrameTab(data) {
      const { originId, tab } = data;
      let targetTab = this.frameTabs.find(({ id }) => id === originId)
        || this.frameTabs.find(({ id }) => id === tab.id);
      if (!targetTab)
        return console.error('targetTab is not found', originId, tab);
      Object.assign(targetTab, tab);
    },

    /**
     * 打开服务备注表单设计器
     */
    openRemarkDesign() {
      // this.remarkDesignModal = true;
      let remarkDesignTab = new Tab({
        id: 'serviceRemarkEdit',
        url: '/setting/serviceRemark',
        title: '服务备注表单设计',
        show: true,
      });
      this.openFrameTab(remarkDesignTab);
    },
    /**
     * 打开服务商管理表单设计器
     */
    openServiceManageDesign(data) {
      let serviceDesignTab = new Tab({
        id: data.id,
        url: data.url,
        title: data.title,
        show: true
      })
      this.openFrameTab(serviceDesignTab);
    },
    openDocumentQuote(event, data) {
      this.documentQuoteShow = true;
      this.documentQuoteFrame = data.tabId; // TODO event.source 钉钉端不支持source？？？ 改为id查找
    },
    /**
     * 打开链接
     */
    openLink(url) {
      platform.openLink(url);
    },
    /**
     * module调用fe中的$fast
     */
    async moduleUseFast(event) {
      const { data, source } = event;
      const { namespace, method, params = [], tabId } = data.data;
      if (typeof params[1] == 'string') {
        params[1] = JSON.parse(params[1]);
      }

      const scope = this.$fast[namespace];
      try {
        if (!scope) throw `${namespace} is not defined`;
        const fn = scope[method];
        if (!fn) `${method} is not defined`;
        const res = await fn(...params);
        this.framePostMessage(this.findTab(tabId), {
          action: 'shb.fast.success',
          data: res,
        });
        // TODO 钉钉端不支持souce.postMessage
        // source.postMessage({
        //   action: 'shb.fast.success',
        //   data: res,
        // }, '*');
      } catch (err) {
        console.error('fast fail:', event);
        this.framePostMessage(this.findTab(tabId), {
          action: 'shb.fast.fail',
          data: err,
        });
        // TODO 钉钉端不支持souce.postMessage
        // source.postMessage({
        //   action: 'shb.fast.fail',
        //   data: err,
        // }, '*');
      }
    },

    /**
     * 选中知识库文档 传回给module
     * @param {*} doc
     */
    handleChooseDocument(doc) {
      // TODO 钉钉端不支持souce.postMessage
      // if(this.documentQuoteFrame){
      //   this.documentQuoteFrame.postMessage({
      //     action: 'shb.system.chooseDcoumentQuote',
      //     data: {
      //       doc,
      //     },
      //   }, '*');
      // }
      this.framePostMessage(this.findTab(this.documentQuoteFrame), {
        action: 'shb.system.chooseDcoumentQuote',
        data: {
          doc,
        },
      });
    },
    // 通过id查找tab
    findTab(id) {
      const tab = this.frameTabs.find(item => item.id === id);
      return tab;
    },
    /** @deprecated 兼容旧页面，迁移完成后删除 */
    addTabs(option) {
      console.warn('不推荐调用该方法，使用 platform.openForFrame 替代');
      this.openForFrame(option);
    },
    /** 用于从导航菜单打开tab */
    openForNav(menu) {
      window.TDAPP.onEvent(
        `pc：访问${menu.name || `未命名页面${menu.menuKey || ''}`}`
      );
      // 这里判断菜单打开方式
      if (menu.openType == 2) return platform.openLink(menu.url);
      let url = this.joinParams(menu.url);
      // if(menu.menuKey.startsWith('M_WINDOW_')) {
      //   // 窗口菜单
      //   url = `/custom_menu_url?url=${menu.url}`
      // }
      let tab = new Tab({
        id: menu.menuKey,
        url,
        title: menu.name,
      });
      this.openFrameTab(tab);
    },
    /**
     * new Tab
     * @param {Object} param0
     * @returns Tab
     */
    createTab({ id, url = '', title = '' }) {
      return new Tab({
        id: id || +safeNewDate(),
        url,
        title,
      });
    },
    /**
     * 给frame发消息
     * @param {*} tab
     * @param {*} message
     */
    framePostMessage(tab, message = {}) {
      const name = `frame_tab_${tab.id}`;
      const frame = document.getElementById(name);
      if (!frame) return console.error(`frame: ${name}, 不存在`);
      frame.contentWindow.postMessage(message, '*');
    },
    /**
     * 用于从其他iframe中打开新的tab
     * option: {id,title,close,url,fromId}
     */
    openForFrame(option) {
      // 页面跳转埋点
      let fromTitle = '首页';
      let fromTabId = '';
      let fromTab = null;
      let pageArr = [];
      // 只有返回页面 isHistory 才为false
      const { isHistory = true, fromId, pageHistory } = option;
      if(fromId) {
        if(fromId.includes('frame_tab_')){
          const fid = fromId.split('frame_tab_');
          fromTabId = fid[1];
        }else{
          fromTabId = fromId
        }
        fromTab  = this.frameTabs.find(item => item.id === fromTabId);
        if(fromTab) {
          fromTitle = fromTab.defaultTitle || fromTab.originTitle || '';
        } else {
          fromTitle = '';
          if(window.closedTabs.length) {
            const closeFromTab  = window.closedTabs.find(item => item.id === fromTabId);
            fromTitle = closeFromTab.defaultTitle || closeFromTab.originTitle || '未知';
          }
        }
        if(isHistory){
          pageArr = (fromTab && fromTab.pageHistory && _.cloneDeep(fromTab.pageHistory)) || [];
        }
      }
      if(isHistory){
        pageArr.push({...option});
      }else{
        pageArr = _.cloneDeep(pageHistory);
      }
      option.pageHistory = pageArr;
      if(option.closeNowPage){
        this.closeFrameTabById(fromTabId);
      }
			this.$track.clickStat(this.$track.formatParams(
        'OPEN_FRAME_TAB',
				{
          from: fromTitle,
          fromId: option?.fromId || '',
          next: option.title,
          nextId: option.id
         }
      ));

      if(option.isFasterPage){
        // 页面携带快捷搜索条件
        const { pageType, id }  = option;
        const { pageData} = option.isFasterPage;
        let tab_ = this.findActivePage({id});
        sessionStorageSet(`bbx-faster-${pageType}`, JSON.stringify(pageData))
        if(tab_){
          let tab = new Tab(option);
          return this.openFrameTab(tab, true);
          // 如果已经打开了页面 直接强制刷新 TO DO 页面级别的重置而不是资源的重置
          // let iframe = document.getElementById(`frame_tab_${id}`);
          // iframe.contentWindow.postMessage(
          //   {
          //     action: 'shb.frame.fasterPage',
          //     data: {
          //       type:`bbx-faster-${type}`,
          //       data:pageData
          //     },
          //   },
          //   isDev ? '*' : `${window.location.origin}`
          // );
        }
      }
      let tab = new Tab(option);
      this.openFrameTab(tab);
    },
    backToFromTab(id){
      try {
        let fromTabId = '';
        if(id.includes('frame_tab_')){
          const fid = id.split('frame_tab_');
          fromTabId = fid[1];
        }else{
          fromTabId = id
        }
        let fromTab  = this.frameTabs.find(item => item.id === fromTabId);
        let pageHistory = fromTab.pageHistory || [];
        let length = pageHistory.length;
        let pageObj = length > 0 && pageHistory[length-2];
        pageHistory.pop();
        // 返回页面不记录页面历史信息了
        pageObj && this.openForFrame({...pageObj, fromId:id, isHistory:false, closeNowPage:true, pageHistory})
      } catch (error) {
        console.warn(error, 'backToFromTab error try catch');
      }
    },
    // 针对独立拆分的vue模块代码处理load事件
    mountedFrame(data) {
      try {
        let tab_ = data.tab;
        let route_ = data.route;
        let item_ = this.frameTabs.find(item => item.id === tab_.id);
        item_.title = tab_.title;
        item_.originTitle = tab_.title;
        // TODO 先传值后期决定什么作用再处理
        item_.currentUrl = route_.path;
        item_.loading = false;
        item_.reload = false;
        item_.viewType = 'vue';
      } catch (error) {
        console.warn(error, 'error try catch');
      }
    },
    /** 打卡一个frame tab */
    openFrameTab(tab, flash) {
      // 直接点击新建工单则关闭
      if (tab && tab.originTitle === '新建工单') {
        document.getElementById('task-center-view-copy').style.display = 'none';
      }
      tab.timeStamp = safeNewDate();
      let index = _.findIndex(this.frameTabs, item => item.id == tab.id);
      if (index >= 0) {
        let target = this.frameTabs[index];
        target.merge(tab);
        return this.jumpFrameTab(target, flash);
      }
      // 当前tab需要显示则当前激活tab隐藏
      const activeIndex = this.frameTabs.findIndex(item => item.show);
      if(tab.show && activeIndex > -1) this.frameTabs[activeIndex].show = false;
      if(tab.isHome){
        // 如果是工作台放在第一位
        this.frameTabs.unshift(tab);
      }else {
        // 插入到当前激活的后面
        this.frameTabs.splice(activeIndex + 1, 0, tab);
      }

      if (tab.id == 'M_VIP_SPAREPART_LIST') {
        this.currUrl = '/bill';
      } else {
        this.currUrl = tab.url;
      }

      this.adjustFrameTabs(tab);
      this.removeFrameCache(tab.id);
      // 滚动至所在tab
      this.$nextTick(() => this.scrollToTab(tab))

      // 新增tab时隐藏全部选人组件
      useHiddenAllTab();

      // 为该frame添加事件
      this.$nextTick(() => {
        let frame = document.getElementById(`frame_tab_${tab.id}`);
        if (!frame) return;

        let frameWindow = frame.contentWindow;

        // frame页面卸载时，重置刷新icon
        frameWindow.addEventListener('unload', () => (tab.loading = true));
        // 修改tab标题
        platform.setTabTitle({
          id: tab.id,
          title: tab.originTitle || tab.title
        })
      });

      // 进入客户列表时，清除记录的列表搜索参数
      // if (tab.currentUrl === '/customer') {
      //   sessionStorage.removeItem('customer_list_search_status');
      // }
    },
    pageCloseOther(i){
      let index = this.frameTabs.length - 1
      for(index;index>0;index-- ){
        let item = this.frameTabs[index]
        if(item.id !== 'M_HOME' && i!==index){
          this.ProcessingPage(item)
        }
      }
    },
    pageCloseAll(){
      let index = this.frameTabs.length - 1
      for(index;index>0;index-- ){
        let item = this.frameTabs[index]
        if(item.id !== 'M_HOME'){
          this.ProcessingPage(item)
        }
      }
    },
    // 处理特殊页面
    ProcessingPage(frameTab) {
      if (window.location.pathname.indexOf('/trtc/pub-live-house') > -1) {
        // 关闭当前会话
        this.$confirm('关闭页面将自动结束当前通话，确认继续吗？', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
          customClass: 'ShowcustomClass',
        })
          .then(res => {
            // 关闭会话
            let query = parse(frameTab.url.split('?')[1]);
            IMApi.leaveRoom({
              conversationId: query.conversationId,
              roomNumber: query.roomID,
              userId: query.userID,
              userType: query.userType,
              tenantId: query.tenantId,
            }).then(res => {
              // 可能未加入房间，直接关闭弹窗
              this.closeFrameTab(frameTab);
            });
          })
          .catch(err => {});
      }else if(frameTab.url.includes('/trainingManagement/examinationForStudent/edit')){
        return this.framePostMessage(frameTab, {
          action: 'shb.system.beforeCloseFrame'})
      } else {
        this.closeFrameTab(frameTab);
      }
    },
    // 关闭frameTab
    closeFrameTab(frameTab) {
      // sessionStorage.removeItem('customer_list_search_status');

      // 关闭回访工单tab，清空回访按钮缓存
      if (sessionStorage.getItem('reviewType')) {
        sessionStorage.removeItem('reviewType');
        sessionStorage.removeItem('reviewValue');
        sessionStorage.removeItem('evaluateValue');
      }

      if (!frameTab.closeable) return;
      // tab关闭或刷新时 销毁绑定选人组件
      useSelectUserBindTabClose();

      // TODO:迁移完成后删除
      localStorage.removeItem(`frame_tab_${frameTab.id}_idArray`);

      let index = this.frameTabs.indexOf(frameTab);
      if (index >= 0) {
        let adjustTab = this.frameTabs.find(item => item.show);
        let currTab = this.frameTabs.splice(index, 1)[0];

        // 清空历史
        FrameHistoryManager.removeStack(`frame_tab_${frameTab.id}`);

        if (currTab.show) {
          let prevTab = this.frameTabs[index - 1];
          if (null != prevTab) {
            prevTab.show = true;
            adjustTab = prevTab;
            this.currUrl = prevTab.url;
            // 关闭到前一个tab加高亮消息
            this.frameActivatedPage(prevTab)
          }
        }
        if (frameTab.id === 'wx_auth') {
          // 监听 微信授权页面关闭关闭轮询事件
          sessionStorage.setItem('wx_auth_auth_page_close', true);
        }

        this.adjustFrameTabs(adjustTab);
      }
    },
    closeFrameTabById(id) {
      let frameTab = {};
      let tab = this.frameTabs.filter(f => f.id == id);

      if (Array.isArray(tab) && tab.length > 0) {
        frameTab = tab[0];
      }

      // 暂存一下关闭的标签
      window.closedTabs.push(frameTab);
      setTimeout(() => {
        window.closedTabs = [];
      }, 2000)
      
      this.closeFrameTab(frameTab);
    },
    jumpFrameTab(frameTab, flash) {
      // 切换tab隐藏其他 展示自己
      useHiddenOtherTab(frameTab.id);

      this.frameTabs.forEach(item => (item.show = false));
      frameTab.show = true;
      

      this.$emit('input', frameTab.url);
      if(flash){
        this.reloadFrameTab(frameTab, false, true);
      } else if (frameTab.noRedirect) {
        this.reloadFrameTab(frameTab, false);
      } else if (frameTab.reload) {
        this.reloadFrameTab(frameTab, frameTab.isUrlChange);
      }
      
      
      this.frameActivatedPage(frameTab)

      window.getLayoutTabBarWidth && window.getLayoutTabBarWidth();

      this.adjustFrameTabs(frameTab);
      // 滚动至所在tab
      this.$nextTick(() => this.scrollToTab(frameTab))
    },
    updateFrameTab(event, tab) {
      let frame = event.target;
      // 页面加载完成时 发送数据
      this.framePostMessage(tab, {
        action: 'shb.frame.create',
        data: {
          initData: window._init,
          tab,
        },
      });
      try {
        let frameWindow = frame.contentWindow;
        if (/^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(tab.currentUrl)) {
          // 绝对地址，迁移外部项目地址
          tab.title = tab.originTitle || tab.title;
        } else {
          // 相对地址，pc-fe项目内部地址
          tab.title = (tab.title == this.$t('common.base.loading2') || tab.title == '正在加载...'
            ? frameWindow.document.title || tab.originTitle
            : tab.title);
          (tab.id == 'M_HOME' || tab.title === '首页') && (tab.title = this.$t('common.pageTitle.pageHomeView')) // TODO 首页改为工作台 首页是在jsp中，等全量开放后可以删除这一行
          // tab.currentUrl = frameWindow.location.hash
          //   ? `${frameWindow.location.pathname}${frameWindow.location.hash}`
          //   : frameWindow.location.pathname;
          tab.currentUrl = tab.url
        }
        tab.loading = false;
        tab.reload = false;
        this.adjustFrameTabs(tab);
        this.$nextTick(() => {
          // let rootWindow = getRootWindow(window);

          // 传递点击事件，用于关闭顶层window popper
          frameWindow.addEventListener('click', e => {
            const clickEvent = new CustomEvent('click', {
              detail: {
                isTrusted: e.isTrusted,
                isMock: true,
              },
              bubbles: true,
            });
            // rootWindow.document.body.dispatchEvent(clickEvent)
            window.document.dispatchEvent(clickEvent);
          });
        });

        // 记录frame历史
        FrameHistoryManager.push(
          frameWindow.frameElement.id,
          frameWindow.location.href
        );
      } catch (error) {
        console.warn(error, 'error');
        console.log(
          [
            `[frame src]: ${frame.src}`,
            `[tab url]: ${tab.url}`,
            `[tab id]: ${tab.id}`,
            `[tab fromid]: ${tab.fromId}`,
          ].join('\n')
        );
      }
    },
    /** 
     * @description 首页刷新 tab
     * 禅道 bug: http://zentao.shb.ltd/index.php?m=bug&f=view&bugID=36136&tid=z325286i
    */
    async reloadFrameTabByFrameView(tab) {
      // tab 的 url 链接
      const url = tab?.url || ''
      // tab 的 id
      const id = tab?.id || ''
      // 如果 url 有域名 且 不是当前域名 且是 自定义窗口 则刷新
      const isHttpUrl = url.includes('http')
      const isSameOrigin = url.includes(window.location.origin)
      const isWindowTab = id.includes('M_WINDOW')
      const isNeedRedirect = isHttpUrl && isFalsy(isSameOrigin) && isWindowTab
      // 刷新 tab
      this.reloadFrameTab(tab, isNeedRedirect)
    },
    async reloadFrameTab(tab, redirect = false, reload = false) {
      if (tab.timeStamp && safeNewDate() - tab.timeStamp <= 5000) return;
      // tab关闭或刷新时 销毁绑定选人组件
      useSelectUserBindTabClose();

      tab.timeStamp = safeNewDate();
      this.removeFrameCache(tab.id);

      let iframe = document.getElementById(`frame_tab_${tab.id}`);
      const isDev = process.env.NODE_ENV !== 'production';
      // 如果是独立vue模块需要执行vue特有刷新方法
      if (Reflect.has(tab, 'viewType') && tab.viewType == 'vue') {
        // TODO 因为页面刷新太快， 太无感，加个假的加载动画 要是后面需要优化 把这端删了就好了 start
        let title = tab.title;
        tab.loading = true;
        tab.title = this.$t('common.base.loading2');

        await new Promise((resolve) => {
          setTimeout(() => {
            tab.loading = false;
            tab.title = title;
            resolve('reload success')
          }, 2000);
        })
        // TODO 因为页面刷新太快， 太无感，加个假的加载动画 要是后面需要优化 把这端删了就好了 end
        return iframe.contentWindow.postMessage(
          {
            action: 'shb.system.refresh',
            data: {},
          },
          isDev ? '*' : `${window.location.origin}`
        );
      }
      if (null != iframe) {
        if (redirect) return (iframe.src = tab.url);
        // 如果页面由导出刷新方法，调用该方法
        if (typeof iframe.contentWindow.__exports__refresh == 'function' && !reload) {
          return iframe.contentWindow
            .__exports__refresh()
            .then(() => {
              console.log('__exports__refresh');
            })
            .catch(err => console.error(err))
            .finally(() => {
              setTimeout(() => {
                tab.loading = false;
              }, 500);
              if (iframe?.contentWindow?.document) {
                tab.title = tab.originTitle || iframe.contentWindow.document.title;
              }
            });
        }
        iframe.contentWindow.location.reload(true);
      }
    },
    reloadFrameTabById(id) {
      // 啄木鸟监控显示id可能为null
      if (null == id) return;

      // 替换传入的 id 中的 frame_tab_
      id = id.replace(/^frame_tab_/, '');

      let index = _.findIndex(this.frameTabs, item => item.id == id);
      if (index >= 0) {
        this.reloadFrameTab(this.frameTabs[index]);
      }
    },
    // 设置tab loading动画
    setFrameLoadingStatus(options) {
      let id = options.id;
      if (null == id) return;
      let tab = this.frameTabs.filter(f => f.id == id)[0];
      tab.loading = options.loading;
      tab.title = options.title || tab.originTitle;
    },
    // 动态修改tab标题
    setFrameTabTitle(options) {
      
      const originOptionsId = options?.id;
      
      if (!originOptionsId) {
        return;
      }
      
      const optionsId = String(originOptionsId);
      const tabId = optionsId.replace('frame_tab_', '');
      if (!tabId) return;

      let frameTab = this.frameTabs.filter(tab => {
        // 我只做pcoperation的分享标题 其他有的自己加
        if(tab?.id === 'PcUrl' && options?.prefix === '/pcoperation'){
          // 分享连接用url判断
          return tab?.url === options.url
        }
        return tab?.id == tabId || tab?.id?.replace('frame_tab_', '') == tabId
      })[0] || {};

      if (_.isEmpty(frameTab)) {
        return console.warn(
          'Caused: setFrameTabTitle error, because frameTab is empty'
        );
      }

      frameTab.title = options.title;
      frameTab.originTitle = options.title;
    },
    // 根据iframe的id打开对应的tab
    openFrameById(id) {
      let frameTab = {};
      const tabId = id.replace('frame_tab_', '');
      if (!tabId) return;

      let tab = this.frameTabs.filter(f => f.id == tabId);

      if (Array.isArray(tab) && tab.length > 0) {
        frameTab = tab[0];
      }
      if (_.isEmpty(frameTab)) {
        return console.warn(
          'Caused: openFrameById error, because frameTab is empty'
        );
      }

      this.openFrameTab(frameTab);
    },

    tabScroll(event) {
      event.preventDefault();

      let scrollEl = this.$refs.scroll;
      let listEl = this.$refs.list;

      let scrollOffsetWidth = scrollEl.offsetWidth; // 外层容器的宽度
      let listOffsetWidth = listEl.offsetWidth; // tab list的宽度
      let maxOffset = listOffsetWidth - scrollOffsetWidth;
      // 无法滚动
      if (listOffsetWidth <= scrollOffsetWidth) return;

      // let delta = normalizeWheel(event);

      // 1. 兼容不同浏览器的事件
      // 2. 根据方向设置offset
      let direction = event.deltaX != 0
        ? event.deltaX > 0
          ? 1
          : -1 // 存在横向滚动,
        : event.deltaY > 0
          ? 4
          : -4;

      let offset = this.offset + direction * 12;
      if (offset < 0) offset = 0;
      if (offset > maxOffset) offset = maxOffset;

      this.offset = offset;
      this.prevBtnEnable = this.offset > 0;
      this.nextBtnEnable = this.offset < maxOffset;
    },
    /** 显示上一页tab */
    prev() {
      if (!this.prevBtnEnable) return;

      let scrollEl = this.$refs.scroll;
      let listEl = this.$refs.list;

      let scrollOffset = scrollEl.offsetWidth;
      let offset = 0;

      // 如果能滚动，计算上一页offset
      if (
        listEl.offsetWidth > scrollEl.offsetWidth
        && this.offset - scrollOffset > 0
      ) {
        offset = this.offset - scrollOffset;
      }

      this.offsetTransition = true;
      this.offset = offset;
      this.adjustFrameTabs();
    },
    /** 显示下一页tab */
    next() {
      if (!this.nextBtnEnable) return;

      let scrollEl = this.$refs.scroll;
      let listEl = this.$refs.list;

      let scrollOffset = scrollEl.offsetWidth;
      let listWidth = listEl.offsetWidth;
      let maxOffset = listWidth - scrollOffset; // 最大偏移量

      let offset = 0;
      if (listEl.offsetWidth > scrollEl.offsetWidth) {
        offset = this.offset + scrollOffset < maxOffset
          ? this.offset + scrollOffset
          : maxOffset;
      }

      this.offsetTransition = true;
      this.offset = offset;
      this.adjustFrameTabs();
    },
    /** 重新计算frameTabs样式 */
    adjustFrameTabs: _.debounce(function(tab) {
      let scrollEl = this.$refs.scroll;
      let listEl = this.$refs.list;

      if (!scrollEl) return;

      let scrollOffsetWidth = scrollEl.offsetWidth; // 外层容器的宽度
      let listOffsetWidth = listEl.offsetWidth; // tab list的宽度

      // 如果无法滚动，offset置为0
      if (listOffsetWidth <= scrollOffsetWidth) {
        this.offset = 0;
        this.adjustScrollStyle();
        return;
      }

      this.$nextTick(() => {
        // 超出最大滚动范围
        if (this.offset + scrollOffsetWidth > listOffsetWidth) {
          this.offset = listOffsetWidth - scrollOffsetWidth;
        }

        // 显示激活的tab
        if (null != tab && tab.show) this.showActiveTab(tab);
        // 如果显示操作按钮，判断翻页按钮的样式
        this.adjustScrollStyle();
      });
    }, 160),
    /** 显示已激活的tab */
    showActiveTab(frameTab) {
      let tabEl = this.$el.querySelector(`#tab_${frameTab.id}`);
      let scrollEl = this.$refs.scroll;
      let listEl = this.$refs.list;

      let scrollOffsetWidth = scrollEl.offsetWidth;
      let listOffsetWidth = listEl.offsetWidth;
      let maxOffset = listEl.offsetWidth - scrollOffsetWidth; // 最大偏移量

      // 左侧不可见
      if (tabEl.offsetLeft < this.offset + 5) {
        let offset = tabEl.offsetLeft - 5;
        if (offset < 0) offset = 0;
        this.offset = offset;
      }

      // 右侧不可见
      let rightOffset = tabEl.offsetLeft + tabEl.offsetWidth;
      if (this.offset + scrollOffsetWidth < rightOffset + 5) {
        let offset = rightOffset + 5 - scrollOffsetWidth;
        if (offset > maxOffset) offset = maxOffset;

        this.offset = offset;
      }

      // 如果激活的tab是最后一个tab(多个tab情况下),且是可滚动的，重置offset为最大偏移量
      if (
        listOffsetWidth > scrollOffsetWidth
        && this.frameTabs.length > 1
        && frameTab == this.frameTabs[this.frameTabs.length - 1]
      ) {
        this.offset = maxOffset;
      }
    },
    /** 重置翻页按钮样式 */
    adjustScrollStyle() {
      let scrollEl = this.$refs.scroll;
      let listEl = this.$refs.list;

      if (listEl.offsetWidth <= scrollEl.offsetWidth) {
        this.prevBtnEnable = this.nextBtnEnable = false;
        return;
      }

      this.prevBtnEnable = this.offset > 0;
      this.nextBtnEnable = this.offset < listEl.offsetWidth - scrollEl.offsetWidth;
    },
    tabTransitionEnd(event) {
      // 只处理tab list的transform效果
      if (
        event.propertyName != 'transform'
        || !event.target.classList.contains('frame-tabs-list')
      )
        return;
      this.offsetTransition = false;
    },
    resizeHandler() {
      let currTab = this.frameTabs.find(item => item.show);
      this.adjustFrameTabs(currTab);
    },
    // 打开frame前清空缓存
    removeFrameCache(menuKey) {
      if (CACHED_FRAMES.indexOf(menuKey) >= 0) {
        let key = `frame_tab_${menuKey}_cache`;
        localStorage.removeItem(key);
        console.info(`debug: clear localStorage for key [${key}]`);
      }
    },
    handleFrameContextMenu(command){
      let event = {
        target: document.querySelector('.frame-tabs-list'),
        command
      }
      this.closeTabHandler(event)
      this.$nextTick(()=>{
        this.frameContextMenuVisible = false
      })
    },
    closeTabHandler(event) {
      let { target, command } = event;
      let id = target.querySelector('.frame-tab-active')?.id;
      let index = this.frameTabs.findIndex(tab => `tab_${tab.id}` == id);
      if (index < 0) return;

      let tab = this.frameTabs[index];

      if (command == 'itself') return this.closeFrameTab(tab);

      if (command == 'other') {
        this.frameTabs = this.frameTabs.filter(item => {
          if (item != tab && item.closeable) {
            // 清空历史
            FrameHistoryManager.removeStack(`frame_tab_${item.id}`);
            return false;
          }

          return true;
        });

        let adjustTab = this.frameTabs.find(i => i == tab);
        adjustTab.show = true;
        return this.adjustFrameTabs(adjustTab);
      }

      if (command == 'all') {
        this.frameTabs = this.frameTabs.filter(item => {
          if (item.closeable) {
            // 清空历史
            FrameHistoryManager.removeStack(`frame_tab_${item.id}`);
            return false;
          }

          return true;
        });

        let adjustTab = this.frameTabs[this.frameTabs.length - 1];
        adjustTab.show = true;
        return this.adjustFrameTabs(adjustTab);
      }
    },
    conversionUrlWithStorageName(fullUrl) {
      if (!fullUrl) return '';

      let symbol = '?';
      let symbolIndex = fullUrl.indexOf(symbol);
      let url = symbolIndex < 0 ? fullUrl : fullUrl.substr(0, symbolIndex);
      let storageKey = '';

      for (let key in urlMap) {
        if (urlMap[key] == url) {
          storageKey = key;
          break;
        }
      }

      return storagePageMap[storageKey] || '';
    },
    getStoragePageData(fullUrl) {
      let storageKey = this.conversionUrlWithStorageName(fullUrl);

      if (!storageKey) return {};

      let pageData = {};

      try {
        pageData = storageGet(storageKey, '{}');
        pageData = JSON.parse(pageData);
      } catch (err) {
        console.log('hbc: getStoragePageData -> err', err);
      }

      // 存入缓存
      if (Object.keys(pageData).length <= 0) {
        let setPageData = {
          pageSize: 10,
        };
        storageSet(storageKey, JSON.stringify(setPageData));
      }

      return pageData;
    },
    joinParams(fullUrl) {
      if (!fullUrl) return '';

      let symbol = '?';
      let symbolIndex = fullUrl.indexOf(symbol);
      let storageData = this.getStoragePageData(fullUrl);
      let url = fullUrl;
      let startIndex = 0;

      // 拼接参数
      if (symbolIndex < 0) {
        for (let key in storageData) {
          startIndex++;
          startIndex > 1
            ? (url += `&${key}=${storageData[key]}`)
            : (url += `?${key}=${storageData[key]}`);
        }
      } else {
        for (let key in storageData) {
          url += `&${key}=${storageData[key]}`;
        }
      }

      return url;
    },
    updateMenus(){
      UserCenterApi.getMenuForVersion().then(res => {
        const { status, data } = res;
        if (status != 0 || !data) return;
        this.buildNavbarMenus(data.barPageList);
        this.buildMoreMenus(data.morePageList);
      });
    },
    async updateMenusV2(){
        const { data } = await getPcHomePageMenuList() 
        const barPageList = data.barPageList || [];
        const morePageList = data.morePageList || [];
        this.reBuildMenus(barPageList, morePageList)
    },
    buildNavbarMenus(data) {
      this.navBarMenus = data ?? (this.initData?.barPageList || []);
      this.showNavBar = true;
    },
    buildMoreMenus(data) {
      this.moreMenus = data ?? (this.initData?.morePageList || []);
    },
    reBuildMenus(barPageList, morePageList) {
      this.buildNavbarMenus(barPageList)
      this.buildMoreMenus(morePageList)
    },
    /**
     * 打开工作台
     * 需要判断灰度信息
     */
    async openHome(){
      let isNew = false;
      let homeTab = this.findTab('M_HOME')
      if(homeTab){
        // 如果已经有打开了的home直接切换tab
        this.jumpFrameTab(homeTab)
        return
      }
      // 首次打开tab需要判断灰度
      // try {
      //   const data = await fetchInitialData()
      //   isNew = data.workbench && [2, 3, 4, 5].includes(data.edition)
      // }catch(err){
      //   console.error('get workbench initData error', err)
      // }
      isNew = true
      homeTab = new Tab({
        id: 'M_HOME',
        url: isNew ? '/foundation/workBench' : '/home',
        title: this.$t('common.pageTitle.pageHomeView'),
        show: !this.frameTabs.length, // 当前没有打开的页面时显示工作台
        close: false
      });
      this.openFrameTab(homeTab)
    },
    findActivePage(page){

      return this.frameTabs.find(tab => tab.id == page.id) || false

    },
    /**
     * 滚动到指定tab
     */
    scrollToTab(tab){
      this.$refs.frameTabGroupRef?.scrollToTab(tab)
    },

    // 页面浏览时间埋点
    trackTabShow() {
      const duration = this.lastShowTab.showTime ? safeNewDate().getTime() - this.lastShowTab.showTime : 0;

			this.$track.clickStat(this.$track.formatParams(
        'PAGE_STAY_TIME',
				{
          duration,
          name: this.lastShowTab?.defaultTitle || this.lastShowTab?.originTitle || '',
          id: this.lastShowTab?.id || '',
        }
      ));
    },
    /**
     * 描述 tab高亮激活事件
     * @date 2022-12-16
     * @returns {any}
     */
    frameActivatedPage(frameTab) {
      this.$nextTick(()=>{
        let iframe = document.getElementById(`frame_tab_${frameTab.id}`);
        iframe?.contentWindow.postMessage(
          {
            action: 'shb.frame.activatedPage',
            data: {},
          },
          isDev ? '*' : `${window.location.origin}`
        );
      })
    }
  },
  created() {
    window.dd_crm_jsapi = getDataFromCRM;
  },
  mounted() {
    window.addEventListener('message', this.receiveMessage);
    window.addEventListener('resize', this.resizeHandler);

    // TODO: 迁移完成后删除
    window.addTabs = this.addTabs;
    window.closeFrameTabById = this.closeFrameTabById;
    window.setFrameTabTitle = this.setFrameTabTitle;
    window.openFrameById = this.openFrameById;
    window.reBuildMenus = this.reBuildMenus
    window.$fast = this.$fast
    window.closedTabs = [];

    window.frameHistoryBack = function(originWindow) {
      if (originWindow.__shb_pc_frame_history__back_pending__) return;

      originWindow.__shb_pc_frame_history__back_pending__ = true;
      let id = originWindow.frameElement.id;
      let referrer = FrameHistoryManager.getReferrer(id);
      referrer
        ? originWindow.location.replace(referrer)
        : originWindow.location.reload(true);
    };
    this.openHome();

    window.changeTaskVersion = data => {
      this.changeTaskVersion(data);
    };
    window.changeLinkPage = data => {
      for (let index = 0; index < this.frameTabs.length; index++) {
        const element = this.frameTabs[index];
        if (element.id == data.id) {
          this.reloadFrameTab(data);
          break;
        }
      }
    };

    // 处理消息跳转url
    let query = parse(window.location.search);
    let { startTime, endTime, id, projectId } = query;
    let pcUrl = this.initData.pcUrl || query.pcUrl || '';
    if (id) {
      pcUrl += `&id=${id}`;
    }
    if (startTime && endTime) {
      pcUrl += `&startTime=${startTime}&endTime=${endTime}`;
    }

    let title = this.$t('common.base.loading2');
    const pcChannel = parse(pcUrl).pcChannel;
    if(pcChannel === 'paas') { // paas
      title = '表单详情';
    } else if(pcUrl && pcUrl.indexOf('/pcoperation/satisfaction/detail') >= 0) { // 客户满意度
      title = '问卷详情';
    }

    let excelType = query.excelType;
    // 处理消息状态打开后台任务浮窗
    if (excelType == 1) {
      window.parent.showExportList();
      window.parent.exportPopoverToggle(true);
    }

    if (pcUrl)
      this.openForFrame({
        id: 'PcUrl',
        title,
        url: pcUrl,
      });
  },
};

export default FrameManager;
